﻿using IInject.Internal;
using IInject.Registration;

namespace IInject.Resolution
{
	public class TypeDependencyBuilder : ContainerMember, ITypeDependencyBuilder
	{
		private readonly ITypeDependencyResolver _resolver;

		public TypeDependencyBuilder(ITypeDependencyResolver resolver, IContainer container) : base(container)
		{
			_resolver = resolver;
		}

		public ITypeDependencyResolver Resolver
		{
			get
			{
				return _resolver;
			}
		}

		public TypeDependency Build(RegistryContext context)
		{
			if (context.Dependency != null)
			{
				return context.Dependency;
			}

			var dependency = new TypeDependency(context);

			if (context.Scope == Scope.Singleton && context.Instance != null)
			{
				return dependency;
			}

			return FillDependency(dependency);
		}

		private TypeDependency FillDependency(TypeDependency dependency)
		{
			if (dependency.Constructor == null)
			{
				var selector = new MostResolvableConstructorSelector(Container);
				var constructor = selector.Select(dependency);
				var parameters = constructor.GetParameters();

				for (int i = 0; i < parameters.Length; i++)
				{
					constructor.Dependencies.Add(
						_resolver.Resolve(parameters[i].ParameterType)
					);
				}

				dependency.Constructor = constructor;
			}

			return dependency;
		}
	}
}
